import React, {useCallback, useEffect, useRef, useState} from "react"
import {
    addMarketOrderItem, convertMarketOrderToProcurement,
    convertToDeliveryOrder,

    deleteMarketOrderItem, deleteMarketOrderItemSub, downloadImportMarketOrderItemsTemplate,
    getMarketOrderDetail, importMarketOrderItemFromExcel,
    MarketOrderDetail,
    MarketOrderItem,
    submitMarketOrder,
    updateMarketOrderItemAmount, updateMarketOrderItemSubAmount
} from "../../apis/MarketOrderApi";
import {Button, Col, Descriptions, message, Popover, Row, Space, Table, theme, Typography, Upload} from "antd";
import {OffsetDateTime, ZonedDateTime, ZoneId, ZoneOffset} from "@js-joda/core";
import {convertAntdTableToExcel, ExportedColumnProps, useTableSearchTextColumnProps} from "../../utils/AntdTableUtils";
import { getAllGoodsWithMarketInStore, importGoodsFromExcel} from "../../apis/GoodsApi";
import AuthorizationResource from "../../components/AuthorizationResource";
import {DeleteOutlined, QuestionCircleOutlined, UploadOutlined} from "@ant-design/icons";
import DataPageLayout from "../../components/DataPageLayout";
import ArrayUtils from "@zxy-cn/array-utils";
import dashboardPageStore from "../../store/DashboardPageStore";
import {observerDashboardPageWrapper} from "./ObserverDashboardPageWrapper";
import employeeAuthorizationStore from "../../store/EmployeeAuthorizationStore";
import LoadableButton from "../../components/LoadableButton";
import {useNavigate} from "react-router";
import {Link} from "react-router-dom";
import EditOrderItemRow, {EditOrderItemGoodsData} from "../../components/EditOrderItemRow";
import {saveTo, saveWorkbookTo} from "../../utils/FileSaver";
import GoodsTable from "../../components/GoodsTable";
import EditAmountAndUnitPopover from "../EditAmountAndUnitPopover";
import {GoodsAmountAndUnitUseHistoryScope, myDatabase} from "../../database/MyDatabase";
import {useLiveQuery} from "dexie-react-hooks";
import TableColumnSelectModal from "../TableColumnSelectModal";
import {DATE_WITH_TIME_FORMATER} from "../../utils/Date";
import {useSubGoodsTableColumnConfiguration} from "../../utils/SubGoodsHooks";
import ConfirmPopover from "../ConfirmPopover";
import ProcurementSupplierSelectPopover from "../ProcurementSupplierSelectPopover";


export interface pageProps {
    id: number
}

const myPath = "markets/orders/{id}"

const MarketOrderDetailPage: React.FC<pageProps> = ({id}) => {
    const [loading, setLoading] = useState(false)
    const [data, setData] = useState<MarketOrderDetail>()
    const query = useCallback(() => {
        setLoading(true)
        getMarketOrderDetail(id).then(response => {
            dashboardPageStore.setTitle(myPath.replace("{id}", id.toString()), response.data.market.name + "订单")
            setData(response.data)
        }).finally(() => {
            setLoading(false)
        })
    }, [id])

    useEffect(() => {
        query()
    }, [query]);

    let token = theme.useToken();

    let navigate = useNavigate();
    let columnsRef = useRef<ExportedColumnProps<MarketOrderItem>[]>();
    let amountAndUnitHistories = useLiveQuery(() => {
        return myDatabase.goodsAmountAndUnitUseHistory.where({
            scope: GoodsAmountAndUnitUseHistoryScope.MARKET_ORDER,
            resourceId: id,
        }).toArray()
    }, [id]);
    const [openExportColumnSelectModal, setOpenExportColumnSelectModal] = useState(false)

    const [importing, setImporting] = useState(false)

    const [messageApi, contextHolder] = message.useMessage();

    let configSubGoodsColumns = useSubGoodsTableColumnConfiguration<MarketOrderItem>();
    return (
        <>
            {contextHolder}
            {!loading && !!data ? <Descriptions title={"订单明细"}>
                <Descriptions.Item label={"卖场"}>{data?.market?.name}</Descriptions.Item>
                <Descriptions.Item label={"下单人"}>{data?.createdBy?.name}</Descriptions.Item>
                {!!data && <Descriptions.Item
                    label={"下单时间"}>{data.createdDateTime.format(DATE_WITH_TIME_FORMATER)}</Descriptions.Item>}
                {!!data?.submitDateTime && <Descriptions.Item
                    label={"提交时间"}>{data?.submitDateTime.format(DATE_WITH_TIME_FORMATER)}</Descriptions.Item>}
                {!!data?.deliveryDateTime ? <Descriptions.Item
                    label={"送货单开单时间"}>{data.deliveryDateTime.format(DATE_WITH_TIME_FORMATER)}</Descriptions.Item> : undefined}
                <Descriptions.Item label={"编号"}>{data?.number}</Descriptions.Item>
            </Descriptions> : null}
            <Row gutter={8} style={{margin: "12px 0"}}>
                <Col>
                    {!data?.submitDateTime&&employeeAuthorizationStore.hasAuthority("卖场_订单_添加货品") ?
                        <Space size={4}>
                            <Upload fileList={[]}
                                    accept={"application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}
                                    maxCount={1}
                                    beforeUpload={file => {
                                        setImporting(true)
                                        importMarketOrderItemFromExcel(id,file).then(response => {
                                            if (response.data) {
                                                query();
                                                return messageApi.success(`成功导入${response.data}个货品`);
                                            } else {
                                                return messageApi.error(`无货品被导入，请检查格式是否正确`);
                                            }
                                        }).finally(() => {
                                            setImporting(false)
                                        });
                                        return false
                                    }}>
                                <Button icon={<UploadOutlined/>} loading={importing}>导入</Button>
                            </Upload>
                            <Popover title={"导入货品"} content={
                                <Typography>
                                    <Typography.Paragraph>
                                        按照约定的格式上传excel文件。
                                        <Typography.Link onClick={() => {
                                            downloadImportMarketOrderItemsTemplate().then(res => res.data)
                                                .then(blob => {
                                                    saveTo(blob, "导入卖场订单模板.xlsx")
                                                })

                                        }}>下载模板</Typography.Link>
                                    </Typography.Paragraph>
                                    <Typography.Paragraph>
                                        <ul>
                                            <li>相同的条码，和子商品编号会被忽略</li>
                                            <li>必填的属性未填会被忽略</li>
                                        </ul>
                                    </Typography.Paragraph>
                                </Typography>
                            }><QuestionCircleOutlined/></Popover>
                        </Space> : undefined}
                </Col>
                <Col>
                    <LoadableButton onClick={async (_) => {
                        setOpenExportColumnSelectModal(true)
                    }}>
                        导出
                    </LoadableButton>
                    <TableColumnSelectModal cacheKey={"marketOrder"}
                                            availableColumns={["名称", "子商品名称", "条码", "子商品编号", "品牌", "类别", "厂商", "库存", "零售价", "箱规", "数量与单位","数量", "单位","总售价", "备案编号", "注册证编号","备注"]}
                                            open={openExportColumnSelectModal} onConfirm={async fields => {

                        let columns = Array.from(columnsRef.current!!);
                        ArrayUtils.insertAfter(columns, value => value.dataIndex === "amountInOrder", {
                            dataIndex: "amountWithoutUnit",
                            title: "数量",
                            render: (_, record) => {
                                return record.amountInOrder
                            },
                        },)
                        ArrayUtils.insertAfter(columns, value => value.dataIndex === "amountWithoutUnit", {
                            dataIndex: "unit",
                            title: "单位",
                            render: (_, record) => {
                                return record.unit?.name
                            },
                        },)

                        let workbook = await convertAntdTableToExcel(columns, data?.items ?? [], fields);
                        await saveWorkbookTo(workbook, `${data?.market?.name}订单-${data?.submitDateTime ?? data!.createdDateTime.format(DATE_WITH_TIME_FORMATER)}`)
                        setOpenExportColumnSelectModal(false)
                    }} onCancel={_ => setOpenExportColumnSelectModal(false)}/>
                </Col>
                {employeeAuthorizationStore.hasAuthority("卖场_订单_转化为送货单")
                && !data?.deliveryDateTime
                && !!data?.submitDateTime ?
                    <Col>
                        <LoadableButton onClick={async () => {
                            await convertToDeliveryOrder(id);
                            setData({...data!, deliveryDateTime: OffsetDateTime.now()})
                            navigate(`/markets/deliveryOrders/${id}`)
                        }}>开送货单</LoadableButton>
                    </Col> : undefined}
                {employeeAuthorizationStore.hasAuthority("卖场_订单_下单") && !data?.submitDateTime &&
                    <Col>
                        {!!data && <LoadableButton onClick={async (event) => {
                            await submitMarketOrder(data.id)
                            setData({...data!, submitDateTime: OffsetDateTime.now()})
                        }}>
                            提交订单
                        </LoadableButton>}

                    </Col>}
                {<Col>
                    <LoadableButton onClick={async (_) => {
                        // await submitMarketOrder(id)
                        // setData({...data!, submitDateTime: OffsetDateTime.now()})
                    }}>
                        打印
                    </LoadableButton></Col>}
                <div style={{flexGrow: 1}}/>
                <Space>
                    {employeeAuthorizationStore.hasAuthority("卖场_送货单_查询") && !!data?.deliveryDateTime &&
                        <Link to={`/markets/deliveryOrders/${id}`} onClick={event => {
                            event.stopPropagation()
                        }}>
                            <Button type={"link"}>查看送货单</Button>
                        </Link>}
                    {employeeAuthorizationStore.hasAuthority("采购_下单")  && <ProcurementSupplierSelectPopover  onConfirm={async procurementSupplierId => {
                        let procurementId = (await convertMarketOrderToProcurement(id, procurementSupplierId)).data;
                        navigate(`/procurements/${procurementId}`)
                    } } >
                        <Button>生成采购单</Button>
                    </ProcurementSupplierSelectPopover>}
                </Space>
            </Row>

            {((employeeAuthorizationStore.hasAuthority("卖场_订单_下单") && !data?.submitDateTime) || (employeeAuthorizationStore.hasAuthority("卖场_订单_转化为送货单") && !data?.deliveryDateTime)) &&
                !!data &&
                <EditOrderItemRow<EditOrderItemGoodsData & {
                    amountInMarket: number
                    amount: number
                }>
                    request={{editMarketOrderId: id}}
                    fetchGoods={() =>
                        getAllGoodsWithMarketInStore(data.market.id).then(res => {
                            return res.data
                        }).then(data => {
                            return data.flatMap(it => {
                                if (it.subGoodsList && !!it.subGoodsList.length) {
                                    return it.subGoodsList.map(subGoods => ({
                                        ...it,
                                        subGoods: subGoods
                                    }))
                                } else {
                                    return [it]
                                }
                            });
                        })
                    }
                    optionRender={it => {
                        return <div style={{display: 'flex', flexDirection: "column"}}>
                            <Space>
                                <span>{it.subGoods ? `${it.barcode}|${it.subGoods.number}` : it.barcode}</span><span>{it.subGoods ? it.subGoods.name + `（${it.name}）` : it.name}</span>
                            </Space>
                            <Space
                                size={24}><span>卖场存货:{it.amountInMarket ?? "无"}</span><span>库存:{it.amount}</span></Space>
                        </div>;
                    }}
                    onFinish={async (values) => {
                        let existed = amountAndUnitHistories?.find(it => it.goodsId === values.goodsId);
                        if (existed) {
                            myDatabase.goodsAmountAndUnitUseHistory.delete(existed.id!!)
                        }
                        myDatabase.goodsAmountAndUnitUseHistory.add({
                            scope: GoodsAmountAndUnitUseHistoryScope.MARKET_ORDER,
                            resourceId: id,
                            amount: values.amount,
                            unitId: values.unitId,
                            goodsId: values.goodsId
                        })
                        return addMarketOrderItem(id, values).then(() => {
                            query()
                        })
                    }}
                    availableAmountAndUnitHistories={amountAndUnitHistories}
                    existedGoodsKeys={data?.items?.map(it => ({goodsId: it.id, subGoodsId: it.subGoods?.id,})) ?? []}/>}
            <DataPageLayout leftActions={<>
            </>}>

                <GoodsTable<MarketOrderItem> loading={loading}
                                             size={"small"}
                                             summary={() => {
                                                 return <>
                                                     <Table.Summary.Row>
                                                         <Table.Summary.Cell index={0}>总零售金额</Table.Summary.Cell>
                                                         <Table.Summary.Cell
                                                             index={1}>{ArrayUtils.sum(data?.items?.map(it => it.amountInOrder * it.price) ?? []).toFixed(2)}</Table.Summary.Cell>
                                                     </Table.Summary.Row>
                                                 </>
                                             }}
                                             customColumns={columns => {
                                                 configSubGoodsColumns(columns)
                                                 ArrayUtils.insertAfter(columns, value => value.dataIndex === "price", {
                                                     dataIndex: "totalPrice",
                                                     title: "总售价",
                                                     render: (_, record) => {
                                                         return Number((record.amountInOrder * record.price).toFixed(2))
                                                     },
                                                 },)
                                                 ArrayUtils.insertAfter(columns, value => value.dataIndex === "name", {
                                                     dataIndex: "amountInOrder",
                                                     title: "数量与单位",
                                                     render: (value, record) => {
                                                         return <div
                                                             style={{color: record.amountInOrder * Math.max(record.units.find(it => it.id === record.unit?.id)?.basicMultiple ?? 0, 1) > record.amount && !data?.deliveryDateTime ? token.token.colorError : undefined}}>{value}{record.unit?.name ?? ""}</div>
                                                     },
                                                     generateExcelValue: (value, record) => {
                                                         return `${value}${record.unit?.name ?? ""}`
                                                     }
                                                 },)
                                                 columns.push({
                                                     dataIndex:"note",
                                                     title:"备注",
                                                 })
                                                 columns.push({
                                                     ignoreInExcel: true,
                                                     title: "操作",
                                                     fixed: "right",
                                                     render: (_, item, __) => {
                                                         return <>
                                                             {employeeAuthorizationStore.hasAuthority("卖场_订单_下单") && !data?.deliveryDateTime &&
                                                                 <EditAmountAndUnitPopover units={item.units}
                                                                                           initialData={{
                                                                                               amount: item.amountInOrder,
                                                                                               unitId: item.unit?.id
                                                                                           }}
                                                                                           onConfirm={async value => {
                                                                                               if (item.subGoods) {
                                                                                                   await updateMarketOrderItemSubAmount(id, item.id, value, item.subGoods.id)
                                                                                               } else {
                                                                                                   await updateMarketOrderItemAmount(id, item.id, value)
                                                                                               }
                                                                                               let index = data?.items.findIndex(it => it.id === item.id && it.subGoods?.id === item.subGoods?.id)!!;
                                                                                               let items = Array.from(data?.items ?? []);
                                                                                               items[index].amountInOrder = value.amount
                                                                                               items[index].unit = item.units.find(it => it.id === value.unitId)
                                                                                               setData({
                                                                                                   ...data!,
                                                                                                   items
                                                                                               })
                                                                                           }}>
                                                                     <Button type={"link"} onClick={(event) => {
                                                                         event.stopPropagation()
                                                                     }}>修改数量</Button>
                                                                 </EditAmountAndUnitPopover>}

                                                             <AuthorizationResource
                                                                 authorities={["卖场_订单_添加货品"]}>
                                                                 <Button type={"link"}
                                                                         danger
                                                                         onClick={async (event) => {
                                                                             event.stopPropagation()
                                                                             if (item.subGoods) {
                                                                                 await deleteMarketOrderItemSub(id, item.id, item.subGoods.id)
                                                                             } else {
                                                                                 await deleteMarketOrderItem(id, item.id)
                                                                             }
                                                                             let items = Array.from(data!.items);
                                                                             ArrayUtils.remove(items, item)
                                                                             setData({
                                                                                 ...data!,
                                                                                 items
                                                                             })
                                                                         }}>
                                                                     <DeleteOutlined/>
                                                                     删除
                                                                 </Button>
                                                             </AuthorizationResource>
                                                         </>
                                                     }

                                                 },);

                                                 columnsRef.current = columns;
                                                 return columns;
                                             }}
                                             rowKey={(record, index) => {
                                                 return record.id.toString() + (record.subGoods?.id ?? "")
                                             }} data={data?.items ?? []}>
                </GoodsTable>
            </DataPageLayout>

        </>
    )
}

export default observerDashboardPageWrapper(MarketOrderDetailPage, myPath, "卖场订单详情")

